package com.pactera.madp.cp.common.util.wx;

import cn.hutool.core.util.CharsetUtil;
import com.pactera.madp.common.core.util.SpringContextHolder;
import com.pactera.madp.cp.api.entity.wx.WinXinEntity;
import com.pactera.madp.cp.config.WxProxyConfig;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.IOException;
import java.io.InputStream;
import java.net.*;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 微信工具
 */
public class WeiXinUtil {

    private static final String PROXY_HOST = WxProxyConfig.getIp();/*"6.34.0.30";*/
    private static final Integer PROXY_PORT = WxProxyConfig.getPort();/*3128;*/
    private static final Boolean IS_PROXY = WxProxyConfig.isEnabled();/*false;*/

    /**
     * 获取微信签名
     * @param url  问号之后的内容需进行URL编码
     * @param ticket  票据
     * @return
     */
    public static WinXinEntity getWinXinEntity(String url, String ticket) {
        WinXinEntity wx = new WinXinEntity();

        Map<String, String> ret = Sign.sign(ticket, url);

        wx.setTicket(ret.get("jsapi_ticket"));
        wx.setSignature(ret.get("signature"));
        wx.setNoncestr(ret.get("nonceStr"));
        wx.setTimestamp(ret.get("timestamp"));
        return wx;
    }

    /**
     * 获取微信签名
     * @param url  问号之后的内容需进行URL编码
     * @return
     */
    public static WinXinEntity getWinXinEntity(String url, String appId, String secret) {
        WinXinEntity wx = new WinXinEntity();
        String ticket = null;
        RedisTemplate redisTemplate = SpringContextHolder.getBean("redisTemplate");
        Boolean lastTicket = redisTemplate.hasKey("ticket");
        if (!lastTicket) {
            synchronized(WeiXinUtil.class) {
                lastTicket = redisTemplate.hasKey("ticket");
                if (lastTicket) {
                    ticket = (String)redisTemplate.opsForValue().get("ticket");
                } else {
                    String access_token = WxAccountApiUtils.getAccountAccessToken(appId, secret);
                    ticket = WxAccountApiUtils.getAccountTicket(access_token);
                    redisTemplate.opsForValue().set("ticket",ticket,6000, TimeUnit.SECONDS);
                }
            }
        } else {
            ticket = (String)redisTemplate.opsForValue().get("ticket");
        }

        Map<String, String> ret = Sign.sign(ticket, url);

        wx.setTicket(ret.get("jsapi_ticket"));
        wx.setSignature(ret.get("signature"));
        wx.setNoncestr(ret.get("nonceStr"));
        wx.setTimestamp(ret.get("timestamp"));
        wx.setAppId(appId);
        return wx;
    }


    /**
     * 获取用户code和openId
     * @param code
     * @return
     */
    public static String getWxEntityByCode(String code, String appId, String secret) throws Exception {
        InputStream is = null;
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret="+ secret +"&code="+ code +"&grant_type=authorization_code";
        String message = "";
        try {
            URL urlPost = new URL(url);
            HttpURLConnection http = (HttpURLConnection) urlPost.openConnection();
            http.setRequestMethod("POST");
            http.setDoInput(true);
            http.setDoOutput(true);
            http.connect();
            is = http.getInputStream();
            int size = is.available();
            byte[] jsonBytes = new byte[size];
            is.read(jsonBytes);
            message = new String(jsonBytes, CharsetUtil.CHARSET_UTF_8);
        }catch (Exception e){
            throw new RuntimeException(e);
        }finally {
        	try {
				if(is != null){
					is.close();
				}
			}catch (Exception ex){
        		ex.printStackTrace();
			}
        }
        return message;
    }

    /**
     * 获取没有code时跳转url
     * @param url
     * @return
     */
    public static String getNoCodeToUrl(String url, String appId) throws Exception{
        String noCodeToUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base&state=0#wechat_redirect";
        url = URLEncoder.encode(url, CharsetUtil.UTF_8);
        noCodeToUrl = noCodeToUrl.replace("REDIRECT_URI", url);
        return noCodeToUrl;
    }

    public static String getWxinUserInfo(String accessToken, String openid) throws Exception {
        InputStream is = null;
        String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN";
        String message = "";
        try {
            HttpURLConnection http = getConnect(url);
            http.setRequestMethod("GET");
            http.setDoInput(true);
            http.setDoOutput(true);
            http.connect();
            is = http.getInputStream();
            int size = is.available();
            byte[] jsonBytes = new byte[size];
            is.read(jsonBytes);
            message = new String(jsonBytes, CharsetUtil.CHARSET_UTF_8);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if(is != null){
                    is.close();
                }
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
        return message;
    }


    public static String doGet(String url) {
        InputStream is = null;
        String message = "";
        try {
            URL _url = new URL(url);
            HttpURLConnection http = (HttpURLConnection) _url.openConnection();
            http.setRequestMethod("GET");
            http.setDoInput(true);
            http.setDoOutput(true);
            http.connect();
            int code = http.getResponseCode();
            if (code != 200) {
                throw new RuntimeException("HTTP Request Failed, code=" + code);
            }
            is = http.getInputStream();
//            int size = is.available();
//            byte[] jsonBytes = new byte[size];
//            is.read(jsonBytes);
//            message = new String(jsonBytes, CharsetUtil.CHARSET_UTF_8);
            int len;
            byte[] bytes = new byte[1024];
            StringBuilder sb = new StringBuilder();
            while ((len = is.read(bytes)) != -1) {
                sb.append(new String(bytes,0, len));
            }
            message = sb.toString();
        }catch (Exception e){
            throw new RuntimeException(e);
        }finally {
            try {
                if(is != null){
                    is.close();
                }
            }catch (Exception ex){
                ex.printStackTrace();
            }
        }
        return message;
    }

    private static HttpURLConnection getConnect(String url) throws IOException {
        URL _url = new URL(url);
        HttpURLConnection http;
        if (IS_PROXY) {
            // 创建代理服务器
            InetSocketAddress addr = new InetSocketAddress(PROXY_HOST, PROXY_PORT);
            // http 代理
            Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);
            // 试图连接并取得返回状态码
            http = (HttpURLConnection) _url.openConnection(proxy);
        } else {
            http = (HttpURLConnection) _url.openConnection();
        }
        return http;
    }

}
